package cn.lili.modules.order.order.service;

import cn.lili.common.vo.ResponseBean;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.distribution.entity.vos.DistributionOrderSearchParams;
import cn.lili.modules.distribution.entity.vos.HomeResult;
import cn.lili.modules.goods.entity.vos.yunxin.BeforeCheckVO;
import cn.lili.modules.goods.entity.vos.yunxin.CallBackVO;
import cn.lili.modules.goods.entity.vos.yunxin.SpuVO;
import cn.lili.modules.goods.entity.vos.yunxin.*;
import cn.lili.modules.member.entity.dos.UserAddress;
import cn.lili.modules.goods.entity.vos.yunxin.BeforeCheckVO;
import cn.lili.modules.goods.entity.vos.yunxin.CallBackVO;
import cn.lili.modules.goods.entity.vos.yunxin.SpuVO;
import cn.lili.modules.member.entity.dto.CityDistributionDTO;
import cn.lili.modules.member.entity.dto.MemberAddressDTO;
import cn.lili.modules.member.entity.vo.CityDistributionVO;
import cn.lili.modules.order.aftersale.entity.dos.AfterSale;
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
import cn.lili.modules.order.order.entity.dos.Order;
import cn.lili.modules.order.order.entity.dos.OrderItem;
import cn.lili.modules.order.order.entity.dto.OrderDTO;
import cn.lili.modules.order.order.entity.dto.OrderExportDTO;
import cn.lili.modules.order.order.entity.dto.OrderMessage;
import cn.lili.modules.order.order.entity.dto.OrderSearchParams;
import cn.lili.modules.order.order.entity.params.DirectPushOrderParams;
import cn.lili.modules.order.order.entity.vo.*;
import cn.lili.modules.payment.entity.dos.PaymentLog;
import cn.lili.modules.store.entity.params.StoreSaleTopParams;
import cn.lili.modules.store.entity.vos.StoreSaleTopVO;
import cn.lili.modules.system.entity.vo.Traces;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import org.apache.ibatis.annotations.Param;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.ResponseEntity;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 子订单业务层
 *
 * @author Chopper
 * @since 2020/11/17 7:36 下午
 */
public interface OrderService extends IService<Order> {


    /**
     * 系统取消订单
     *
     * @param orderSn 订单编号
     * @param reason  错误原因
     */
    void systemCancel(String orderSn, String reason);

    /**
     * 根据sn查询
     *
     * @param orderSn 订单编号
     * @return 订单信息
     */
    Order getBySn(String orderSn);

    /**
     * 查询订单，判定是否可以发货
     *
     * @param orderSn 订单编号
     * @return 订单信息
     */
    Order checkDeliver(String orderSn);

    /**
     * 根据sn查询
     *
     * @param orderSn 订单编号
     * @return 订单信息
     */
    Order getBySnNoAuth(String orderSn);

    /**
     * 订单查询
     *
     * @param orderSearchParams 查询参数
     * @return 简短订单分页
     */
    Page<OrderSimpleVO> queryByParams(OrderSearchParams orderSearchParams);

    /**
     * 分销订单查询
     * @param distributionOrderSearchParams
     * @return
     */
    Page<OrderSimpleVO> distributionQuery(DistributionOrderSearchParams distributionOrderSearchParams);

    /**
     * 订单信息
     *
     * @param orderSearchParams 查询参数
     * @return 订单信息
     */
    List<Order> queryListByParams(OrderSearchParams orderSearchParams);

    /**
     * 根据促销查询订单
     *
     * @param orderPromotionType 订单类型
     * @param payStatus          支付状态
     * @param parentOrderSn      依赖订单编号
     * @param orderSn            订单编号
     * @return 订单信息
     */
    List<Order> queryListByPromotion(String orderPromotionType, String payStatus, String parentOrderSn, String orderSn);

    /**
     * 根据促销查询订单
     *
     * @param orderPromotionType 订单类型
     * @param payStatus          支付状态
     * @param parentOrderSn      依赖订单编号
     * @param promotionId        促销id
     * @param skuId              商品skuId
     * @return 订单信息
     */
    List<Order> queryListByPromotionId(String orderPromotionType, String payStatus, String parentOrderSn, String promotionId, String skuId);

    /**
     * 根据促销查询订单
     *
     * @param orderPromotionType 订单类型
     * @param payStatus          支付状态
     * @param parentOrderSn      依赖订单编号
     * @param orderSn            订单编号
     * @return 订单信息
     */
    long queryCountByPromotion(String orderPromotionType, String payStatus, String parentOrderSn, String orderSn);

    /**
     * 父级拼团订单分组
     *
     * @param pintuanId 拼团id
     * @return 拼团订单信息
     */
    List<Order> queryListByPromotion(String pintuanId);


    /**
     * 查询导出订单列表
     *
     * @param orderSearchParams 查询参数
     * @return 导出订单列表
     */
    List<OrderExportDTO> queryExportOrder(OrderSearchParams orderSearchParams);

    ResponseEntity<InputStreamResource> exportExcelByOrder (OrderSearchParams orderSearchParams);

    /**
     * 查询导出待发货订单列表
     *
     * @param orderSearchParams 查询参数
     * @return 导出订单列表
     */
    List<OrderExportDTO> queryExportOrderByWaitShip(OrderSearchParams orderSearchParams);


    /**
     * 订单详细
     *
     * @param orderSn 订单SN
     * @return 订单详细
     */
    OrderDetailVO queryDetail(String orderSn);

    /**
     * 创建订单
     * 1.检查交易信息
     * 2.循环交易购物车列表，创建订单以及相关信息
     *
     * @param tradeDTO 交易DTO
     */
    void intoDB(TradeDTO tradeDTO);

    /**
     * 订单付款
     * 修改订单付款信息
     * 记录订单流水
     *
     * @param paymentLog 支付日志
     */
    Order payOrder(PaymentLog paymentLog);

    /**
     * 订单付款 0元支付场景
     *
     * @param sn 交易编号
     */
    void payOrderZero(String sn);

    /**
     * 订单确认成功
     *
     * @param orderSn
     */
    void afterOrderConfirm(String orderSn);

    /**
     * 取消订单 普通单+供应链单取消
     *
     * @param orderSn 订单SN
     * @param reason  取消理由
     * @return 订单
     */
    Order cancel(String orderSn, String reason,String resultId, String ...uid);

    public Boolean appOrderAfterSalesCreate(Order order, AfterSale afterSale);
    /**
     * 拒绝取消订单
     *
     * @param orderSn 订单SN
     * @return 订单
     */
    Order cancelResult(String orderSn,String id);

    /**
     * 售后取消订单
     * 易邦久回调专用
     */
    Order cancel(String orderSn, String reason, String uid);


    /**
     * 发货信息修改
     * 日志功能内部实现
     *
     * @param orderSn          订单编号
     * @param memberAddressDTO 收货地址信息
     * @return 订单
     */
    Order updateConsignee(String orderSn, MemberAddressDTO memberAddressDTO);

    /**
     * 订单发货
     *
     * @param orderSn       订单编号
     * @param invoiceNumber 发货单号
     * @param logisticsId   物流公司
     * @return 订单
     */
    Order delivery(String orderSn, String invoiceNumber, String logisticsId);

    /**
     * 订单览件
     *
     * @param orderSns       订单编号
     * @return 订单
     */
    Boolean overview(String orderSns);

    /**
     * 取消订单览件
     *
     * @param orderSns       订单编号
     * @return 订单
     */
    Boolean overviewOut(String orderSns);

    /**
     * 获取物流踪迹
     *
     * @param orderSn 订单编号
     * @return 物流踪迹
     */
    Traces getTraces(String orderSn);

    /**
     * 订单核验
     *
     * @param verificationCode 验证码
     * @param orderSn          订单编号
     * @return 订单
     */
    Order take(String orderSn, String verificationCode);

    /**
     * 根据核验码获取订单信息
     *
     * @param verificationCode 验证码
     * @return 订单
     */
    Order getOrderByVerificationCode(String verificationCode);

    /**
     * 订单完成
     *
     * @param orderSn 订单编号
     */
    void complete(String orderSn);

    /**
     * 系统定时完成订单
     *
     * @param orderSn 订单编号
     */
    void systemComplete(String orderSn);

    /**
     * 通过trade 获取订单列表
     *
     * @param tradeSn 交易编号
     * @return 订单列表
     */
    List<Order> getByTradeSn(String tradeSn);

    /**
     * 通过父订单号
     * @return
     */
    List<Order> getByParentSn(String sn);

    /**
     * 发送更新订单状态的信息
     *
     * @param orderMessage 订单传输信息
     */
    void sendUpdateStatusMessage(OrderMessage orderMessage);

    /**
     * 根据订单sn逻辑删除订单
     *
     * @param sn 订单sn
     */
    void deleteOrder(String sn);

    /**
     * 开具发票
     *
     * @param sn 订单sn
     * @return
     */
    Boolean invoice(String sn);

    /**
     * 自动成团订单处理
     *
     * @param pintuanId     拼团活动id
     * @param parentOrderSn 拼团订单sn
     */
    void agglomeratePintuanOrder(String pintuanId, String parentOrderSn);

    /**
     * 获取待发货订单编号列表
     *
     * @param response      响应
     * @param logisticsName 店铺已选择物流公司列表
     */
    void getBatchDeliverList(HttpServletResponse response, List<String> logisticsName);

    /**
     * 订单批量发货
     *
     * @param files 文件
     */
    void batchDeliver(MultipartFile files);


    /**
     * 查询订单支付记录
     *
     * @param page         分页
     * @param queryWrapper 查询条件
     * @return 订单支付记录分页
     */
    Page<PaymentLog> queryPaymentLogs(Page<PaymentLog> page, Wrapper<PaymentLog> queryWrapper);

    /**
     * 检查是否开始虚拟成团
     *
     * @param pintuanId   拼团活动id
     * @param requiredNum 成团人数
     * @param fictitious  是否开启成团
     * @return 是否成功
     */
    boolean checkFictitiousOrder(String pintuanId, Integer requiredNum, Boolean fictitious);

    /**
     * 供应商订单统计
     *
     * @param supplierId
     * @return
     */
    Map<String, Long> pendingPaymentOrderNum(String supplierId);

    ResponseBean callback(CallBackVO callBackVO);

    public JSONObject beforeCheck(BeforeCheckVO beforeCheckVO);

    public JSONObject appOrder(List<SpuVO> spuVOList, BeforeCheckVO beforeCheckVO, String orderSn, String remark);

    void conversionAddress(BeforeCheckVO checkRes, String idPath);

    public JSONObject afterSalesSend(OrderItem orderItem, String company_name, String company_code, String express_no);

    public JSONObject afterSalesClose(OrderItem orderItem);

    ResultMessage<Object> vipComputePrice();

    public Map<String, Object> sumPrice();

    ResultMessage<Object> vipOrderPrice(OrderSearchParams orderSearchParams);

    ResultMessage<Object> recycle(String id, String recycleRemark);

    Page<StoreSaleTopVO> saleRankByOrder (StoreSaleTopParams params);

    List<RegionalGroupingVO> regionalGrouping();

    LambdaQueryWrapper<Order> createWrapperDirectPushOrderList(DirectPushOrderParams pushOrderParams);

    OrderVO todayOrderForUnion(String province, String city);

    OrderVO todayOrderForUnion(List<String> buyerIdList);

    Page<OrderVO> getOrderByPage (String province,String city,Integer pageSize,Integer pageNo);

    /**
     * 城主收益详情
     * @param dto
     * @return
     */
    CityDistributionVO getCityDistributionComissList(CityDistributionDTO dto);

    /**
     * 是否存在未完成的订单
     * @param joinAddress
     * @param startLocalDate
     * @param endLocalDate
     * @return
     */
    Boolean isExistsUnCompletedOrder(String joinAddress, LocalDate startLocalDate, LocalDate endLocalDate);

    Boolean isExistsUnCompletedOrderByOc(String joinAddress, LocalDate startLocalDate, LocalDate endLocalDate);

    /**
     * 定时任务城主分佣统计
     * @param
     * @return
     */
    List<OrderItemViewVO> getCityDistributionSumComissByTaskTime(Integer pageNum, Integer pageSize, String joinAddress, LocalDate startLocalDate, LocalDate endLocalDate);

    List<OrderItemViewVO> getUnionSumComissByTaskTime(Integer pageNum, Integer pageSize, String joinAddress, LocalDate startLocalDate, LocalDate endLocalDate);

    List<String> executeCityDistributionLastMonthOrder(LocalDateTime begin, LocalDateTime end, Integer subDistributionCount);

    Page<OrderVO> getOrderByPage(List<String> buyerIdList, Integer pageNo, Integer pageSize);

    /**
     * 根据区域查询所有月份
     * @param
     * @return
     */
    Page<UnionMonthFundsVO> getOrderMonth (UnionOrderParams params);

    /**
     * 根据区域查询所有订单
     * @param regionId
     * @return
     */
    List<String> getOrderSnByMonth (String regionId, String month);

    /**
     * 推送订单给第三方平台
     * @return
     */
    ResultMessage<Object> pushOrderToThirdGrabOrder(String orderNos);

    /**
     * 手动处理支付未成功订单补偿
     * @param order
     * @return
     */
    ResultMessage<Object> handlePayNotSuccessOrder(Order order);

    /**
     * 首页订单数量统计
     */
    ResultMessage<HomeResult> orderQuantityStatistics();

    /***
     * 收货地址为运营中心本省的分销订单列表
     * @param vo
     * @return
     */
    Page<OrderViewVO> getOperationCenterOrderList(OrderViewVO vo);

    /**
     * 订单数量统计
     * @return
     */
    ResultMessage<HomeResult> operationCenterOrderStatistics();

    DataStatisticsResult dataStatistics(String scene, String startDate, String endDate,Boolean isNeedProcessDate);

    /**
     * 获取礼包订单列表
     * @param dto
     * @return
     */
    Page<OrderVO> getPackGiftOrderList(OrderDTO dto);

    /**
     * 数据统计
     * @param type 1日， 2周， 3月， 4季度
     */
    ResultMessage<Object> dataAnalysis(String scene, Integer type);

    /**
     * 根据订单号获取礼包订单的类型
     * @param orderSn
     * @return
     */
    List<OrderPackVO> getOrderPackInfoByOrderSn(String orderSn);


    /**
     * 根据身份证号码查询免税订单号
     * @param dto
     * @return
     */
    Double sumTotalFreeTaxOrder(OrderDTO dto);

    void syncSupplyChain();

}